<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>星火大模型聊天室</title>
    <style>
        :root {
            /* 默认主题 (绿色) */
            --primary-color: #07C160;
            --primary-hover: #05A151;
            --user-bg: #95EC69;
            --assistant-bg: #F3F3F3;
            --reasoning-bg: #FFF8E6;
            --text-color: #333;
            --light-text: #666;
            --border-color: #E5E5E5;
            --shadow-light: rgba(0, 0, 0, 0.05);
            --header-bg: rgba(255, 255, 255, 0.95);
            --app-bg: rgba(255, 255, 255, 0.85); /* 降低应用背景透明度 */
            --input-bg: rgba(255, 255, 255, 0.9);
            --history-bg: rgba(255, 255, 255, 0.7); /* 降低聊天历史背景透明度 */
            --particle-color: hsl(180, 80%, 60%);
            --sidebar-bg: #f8f8f8;
            --sidebar-width: 280px;
            --sidebar-item-hover: rgba(0, 0, 0, 0.05);
            --sidebar-item-active: rgba(7, 193, 96, 0.1);
            --sidebar-text: #555;
            --sidebar-border: #e0e0e0;
        }

        /* 蓝色主题 */
        .theme-blue {
            --primary-color: #1E88E5;
            --primary-hover: #1565C0;
            --user-bg: #64B5F6;
            --assistant-bg: #E3F2FD;
            --reasoning-bg: #E1F5FE;
            --particle-color: hsl(210, 80%, 60%);
            --sidebar-item-active: rgba(30, 136, 229, 0.1);
        }

        /* 紫色主题 */
        .theme-purple {
            --primary-color: #8E24AA;
            --primary-hover: #6A1B9A;
            --user-bg: #BA68C8;
            --assistant-bg: #F3E5F5;
            --reasoning-bg: #F8F1FF;
            --particle-color: hsl(280, 80%, 60%);
            --sidebar-item-active: rgba(142, 36, 170, 0.1);
        }

        /* 深色主题 */
        .theme-dark {
            --primary-color: #4CAF50;
            --primary-hover: #388E3C;
            --user-bg: #81C784;
            --assistant-bg: #424242;
            --reasoning-bg: #616161;
            --text-color: #E0E0E0;
            --light-text: #B0B0B0;
            --border-color: #303030;
            --shadow-light: rgba(0, 0, 0, 0.2);
            --header-bg: rgba(33, 33, 33, 0.95);
            --app-bg: rgba(48, 48, 48, 0.8); /* 降低应用背景透明度 */
            --input-bg: rgba(66, 66, 66, 0.9);
            --history-bg: rgba(48, 48, 48, 0.6); /* 降低聊天历史背景透明度 */
            --particle-color: hsl(120, 80%, 60%);
            --sidebar-bg: #2d2d2d;
            --sidebar-text: #ccc;
            --sidebar-border: #3d3d3d;
            --sidebar-item-hover: rgba(255, 255, 255, 0.05);
            --sidebar-item-active: rgba(76, 175, 80, 0.2);
            --dark-bg-pattern: rgba(0, 0, 0, 0.05); /* 深色模式特殊背景图案 */
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", STHeiti, "Microsoft Yahei", sans-serif;
            margin: 0;
            padding: 0;
            color: var(--text-color);
            line-height: 1.6;
            -webkit-font-smoothing: antialiased;
            position: relative;
            overflow-x: hidden;
            background-color: #f5f5f5;
        }

        /* 深色模式特殊背景图案 */
        .theme-dark {
            background-image:
                radial-gradient(var(--dark-bg-pattern) 1px, transparent 1px),
                radial-gradient(var(--dark-bg-pattern) 1px, transparent 1px);
            background-size: 50px 50px;
            background-position: 0 0, 25px 25px;
        }

        /* 粒子画布样式 */
        #particle-canvas {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 2; /* 提高粒子画布层级 */
            opacity: 0.6;
            pointer-events: none;
            mix-blend-mode: overlay;
        }

        /* 主布局 */
        .main-layout {
            display: flex;
            min-height: 100vh;
            position: relative;
        }

        /* 侧边栏样式 */
        .sidebar {
            width: var(--sidebar-width);
            background-color: var(--sidebar-bg);
            border-right: 1px solid var(--sidebar-border);
            height: 100vh;
            position: fixed;
            left: 0;
            top: 0;
            overflow-y: auto;
            transition: transform 0.3s ease, background-color 0.3s ease;
            z-index: 100; /* 确保侧边栏在最上层 */
            display: flex;
            flex-direction: column;
        }

        .sidebar-header {
            padding: 15px;
            border-bottom: 1px solid var(--sidebar-border);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .sidebar-title {
            font-size: 16px;
            font-weight: 500;
            color: var(--text-color);
        }

        .sidebar-close {
            background: none;
            border: none;
            color: var(--text-color);
            cursor: pointer;
            padding: 2px;
            display: none;
        }

        .sidebar-search {
            padding: 12px 15px;
            border-bottom: 1px solid var(--sidebar-border);
        }

        #history-search {
            width: 100%;
            padding: 8px 12px;
            border-radius: 4px;
            border: 1px solid var(--sidebar-border);
            background-color: var(--input-bg);
            color: var(--text-color);
            font-size: 14px;
        }

        .sidebar-content {
            flex: 1;
            overflow-y: auto;
            padding: 10px 0;
        }

        .history-list {
            list-style: none;
        }

        .history-item {
            padding: 12px 15px;
            cursor: pointer;
            border-left: 3px solid transparent;
            transition: all 0.2s ease;
            position: relative;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .history-item:hover {
            background-color: var(--sidebar-item-hover);
        }

        .history-item.active {
            background-color: var(--sidebar-item-active);
            border-left-color: var(--primary-color);
        }

        .history-item-title {
            font-size: 14px;
            color: var(--text-color);
            margin-bottom: 4px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .history-item-preview {
            font-size: 12px;
            color: var(--light-text);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .history-item-time {
            font-size: 11px;
            color: var(--light-text);
            margin-top: 4px;
        }

        .sidebar-footer {
            padding: 12px 15px;
            border-top: 1px solid var(--sidebar-border);
            text-align: center;
        }

        .clear-history {
            color: var(--primary-color);
            font-size: 13px;
            background: none;
            border: none;
            cursor: pointer;
            padding: 4px 8px;
            border-radius: 4px;
        }

        .clear-history:hover {
            background-color: var(--sidebar-item-hover);
        }

        /* 应用内容容器 */
        .app-container {
            background-color: var(--app-bg);
            min-height: 100vh;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
            position: relative;
            transition: background-color 0.3s ease;
            margin-left: var(--sidebar-width);
            width: calc(100% - var(--sidebar-width));
            z-index: 2; /* 设置应用容器层级，低于侧边栏但高于粒子画布 */
        }

        .app-header {
            background-color: var(--header-bg);
            padding: 15px 20px;
            box-shadow: 0 1px 2px var(--shadow-light);
            position: sticky;
            top: 0;
            z-index: 10;
            backdrop-filter: blur(5px);
            display: flex;
            justify-content: space-between;
            align-items: center;
            transition: background-color 0.3s ease;
        }

        .app-title {
            color: var(--text-color);
            font-size: 18px;
            font-weight: 500;
            text-align: center;
            flex-grow: 1;
        }

        .header-actions {
            display: flex;
            gap: 10px;
        }

        .header-button {
            background: none;
            border: none;
            color: var(--text-color);
            cursor: pointer;
            padding: 5px;
            border-radius: 4px;
            transition: background-color 0.2s;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .header-button:hover {
            background-color: rgba(0, 0, 0, 0.05);
        }

        .header-button svg {
            width: 20px;
            height: 20px;
            fill: var(--text-color);
        }

        .sidebar-toggle {
            display: none;
        }

        .chat-container {
            height: calc(100vh - 60px);
            display: flex;
            flex-direction: column;
            padding-bottom: env(safe-area-inset-bottom);
            position: relative;
            z-index: 2;
        }

        .model-selector {
            background-color: var(--header-bg);
            padding: 12px 15px;
            display: flex;
            align-items: center;
            border-bottom: 1px solid var(--border-color);
            backdrop-filter: blur(5px);
            transition: background-color 0.3s ease;
        }

        .model-selector label {
            margin-right: 10px;
            font-size: 14px;
            color: var(--light-text);
            white-space: nowrap;
        }

        .model-selector select {
            padding: 6px 10px;
            border-radius: 4px;
            border: 1px solid var(--border-color);
            background-color: var(--input-bg);
            font-size: 14px;
            flex-grow: 1;
            appearance: none;
            background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
            background-repeat: no-repeat;
            background-position: right 8px center;
            background-size: 14px;
            color: var(--text-color);
            transition: all 0.3s ease;
        }

        .chat-history {
            flex: 1;
            overflow-y: auto;
            padding: 15px 12px;
            scroll-behavior: smooth;
            background-color: var(--history-bg); /* 聊天历史背景使用半透明效果 */
            transition: background-color 0.3s ease;
            z-index: 1; /* 设置聊天历史层级 */
        }

        .message {
            margin-bottom: 12px;
            max-width: 80%;
            position: relative;
            animation: fadeIn 0.25s ease;
            word-wrap: break-word;
            z-index: 3; /* 设置消息层级，确保在粒子之上 */
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(8px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .user-message {
            margin-left: auto;
        }

        .assistant-message {
            margin-right: auto;
        }

        .message-bubble {
            padding: 10px 14px;
            border-radius: 18px;
            position: relative;
            line-height: 1.5;
            word-break: break-word;
            white-space: pre-wrap;
            overflow-wrap: break-word;
            text-align: left;
            transition: background-color 0.3s ease;
            z-index: 4; /* 设置消息气泡层级 */
            backdrop-filter: blur(2px); /* 添加模糊效果增强深度感 */
        }

        .user-message .message-bubble {
            background-color: var(--user-bg);
            border-top-right-radius: 4px;
            color: var(--text-color);
        }

        .assistant-message .message-bubble {
            background-color: var(--assistant-bg);
            border-top-left-radius: 4px;
        }

        .reasoning-message {
            font-size: 13px;
            color: var(--light-text);
            margin: 8px 0 8px 10px;
            padding: 8px 12px;
            background-color: var(--reasoning-bg);
            border-radius: 12px;
            max-width: 90%;
            line-height: 1.5;
            word-break: break-word;
            white-space: pre-wrap;
            transition: all 0.3s ease;
            z-index: 3; /* 设置思维链层级 */
            backdrop-filter: blur(2px); /* 添加模糊效果增强深度感 */
        }

        .message-meta {
            display: flex;
            justify-content: space-between;
            margin-top: 4px;
            font-size: 11px;
            color: var(--light-text);
        }

        .input-area {
            background-color: var(--header-bg);
            padding: 10px 15px;
            border-top: 1px solid var(--border-color);
            display: flex;
            align-items: flex-end;
            gap: 10px;
            backdrop-filter: blur(5px);
            transition: background-color 0.3s ease;
            z-index: 10; /* 设置输入区域层级 */
        }

        #message-input {
            flex-grow: 1;
            min-height: 40px;
            max-height: 120px;
            padding: 8px 12px;
            border: 1px solid var(--border-color);
            border-radius: 20px;
            font-size: 16px;
            resize: none;
            outline: none;
            line-height: 1.5;
            overflow-y: auto;
            transition: all 0.3s ease;
            background-color: var(--input-bg);
            color: var(--text-color);
            z-index: 11; /* 设置输入框层级 */
        }

        #message-input:focus {
            border-color: var(--primary-color);
        }

        #message-input::placeholder {
            color: var(--light-text);
        }

        #send-button {
            height: 40px;
            width: 40px;
            border-radius: 50%;
            background-color: var(--primary-color);
            color: white;
            border: none;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: background-color 0.2s;
            flex-shrink: 0;
            z-index: 11; /* 设置发送按钮层级 */
        }

        #send-button:hover {
            background-color: var(--primary-hover);
        }

        #send-button:disabled {
            background-color: #C0C0C0;
            cursor: not-allowed;
        }

        .status {
            height: 20px;
            font-size: 12px;
            color: var(--light-text);
            text-align: center;
            padding: 0 15px 5px;
            background-color: var(--history-bg);
            transition: background-color 0.3s ease;
            z-index: 5; /* 设置状态显示层级 */
        }

        .typing-indicator {
            display: inline-flex;
            align-items: center;
            gap: 4px;
        }

        .typing-dot {
            width: 6px;
            height: 6px;
            background-color: var(--light-text);
            border-radius: 50%;
            animation: typingAnimation 1.4s infinite ease-in-out;
        }

        .typing-dot:nth-child(1) {
            animation-delay: 0s;
        }

        .typing-dot:nth-child(2) {
            animation-delay: 0.2s;
        }

        .typing-dot:nth-child(3) {
            animation-delay: 0.4s;
        }

        @keyframes typingAnimation {
            0%, 60%, 100% {
                transform: translateY(0);
                opacity: 0.6;
            }
            30% {
                transform: translateY(-4px);
                opacity: 1;
            }
        }

        /* 主题选择菜单 */
        .theme-menu {
            position: relative;
            display: inline-block;
        }

        .theme-button {
            background: none;
            border: none;
            cursor: pointer;
            padding: 5px;
            border-radius: 4px;
            transition: background-color 0.2s;
        }

        .theme-button:hover {
            background-color: rgba(0, 0, 0, 0.05);
        }

        .theme-options {
            position: absolute;
            right: 0;
            top: 100%;
            background-color: var(--header-bg);
            border: 1px solid var(--border-color);
            border-radius: 4px;
            box-shadow: 0 2px 8px var(--shadow-light);
            z-index: 20;
            display: none;
            min-width: 120px;
            transition: all 0.3s ease;
        }

        .theme-menu:hover .theme-options {
            display: block;
        }

        .theme-option {
            padding: 8px 12px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: background-color 0.2s;
        }

        .theme-option:hover {
            background-color: rgba(0, 0, 0, 0.05);
        }

        .theme-color {
            width: 16px;
            height: 16px;
            border-radius: 50%;
            border: 1px solid var(--border-color);
        }

        .theme-default .theme-color {
            background-color: #07C160;
        }

        .theme-blue .theme-color {
            background-color: #1E88E5;
        }

        .theme-purple .theme-color {
            background-color: #8E24AA;
        }

        .theme-dark .theme-color {
            background-color: #4CAF50;
        }

        /* 优化中文排版 */
        .message-bubble, .reasoning-message {
            line-break: loose;
            word-break: keep-all;
            text-spacing: ideograph-alpha ideograph-numeric;
            hanging-punctuation: allow-end;
        }

        /* 移动端优化 */
        @media (max-width: 900px) {
            .sidebar {
                transform: translateX(-100%);
                z-index: 1000;
                width: 280px;
            }

            .sidebar.active {
                transform: translateX(0);
            }

            .app-container {
                margin-left: 0;
                width: 100%;
            }

            .sidebar-toggle {
                display: block;
            }

            .sidebar-close {
                display: block;
            }
        }

        @media (max-width: 600px) {
            .chat-container {
                height: calc(100vh - 50px);
            }

            .message {
                max-width: 85%;
            }

            #message-input {
                font-size: 15px;
            }

            .app-header {
                padding: 10px 12px;
                background-color: var(--header-bg);
                box-shadow: 0 1px 2px var(--shadow-light);
                position: sticky;
                top: 0;
                z-index: 3;
                backdrop-filter: blur(5px);
                display: flex;
                justify-content: space-between;
                align-items: center;
                transition: background-color 0.3s ease;

            }

            .model-selector {
                padding: 8px 12px;
            }

            .input-area {
                padding: 8px 12px;
            }
        }

        /* 空状态提示 */
        .empty-state {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100%;
            color: var(--light-text);
            text-align: center;
            padding: 20px;
            z-index: 2; /* 设置空状态提示层级 */
        }

        .empty-state svg {
            width: 60px;
            height: 60px;
            margin-bottom: 15px;
            opacity: 0.6;
        }

        .empty-state p {
            margin-top: 10px;
            font-size: 14px;
        }

        /* 侧边栏动画 */
        .sidebar-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 999;
            display: none;
        }

        @media (max-width: 900px) {
            .sidebar-overlay.active {
                display: block;
            }
        }
    </style>
</head>
<body>
<!-- 粒子画布 -->
<canvas id="particle-canvas"></canvas>

<!-- 侧边栏遮罩 -->
<div class="sidebar-overlay" id="sidebar-overlay"></div>

<!-- 侧边栏 -->
<div class="sidebar" id="sidebar">
    <div class="sidebar-header">
        <div class="sidebar-title">历史对话</div>
        <button class="sidebar-close" id="sidebar-close">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M18 6L6 18M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
        </button>
    </div>

    <div class="sidebar-search">
        <input type="text" id="history-search" placeholder="搜索历史对话...">
    </div>

    <div class="sidebar-content">
        <ul class="history-list" id="history-list">
            <!-- 历史记录将通过JavaScript动态加载 -->
        </ul>
    </div>

    <div class="sidebar-footer">
        <button class="clear-history" id="clear-history">清空历史记录</button>
    </div>
</div>

<!-- 应用主容器 -->
<div class="app-container">
    <div class="app-header">
        <div class="header-actions">
            <button class="header-button sidebar-toggle" id="sidebar-toggle" title="显示历史记录">
                <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path d="M3 12H21M3 6H21M3 18H21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
            </button>
            <button class="header-button" id="new-chat-button" title="新对话">
                <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path d="M12 5V19M5 12H19" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                </svg>
            </button>
        </div>

        <h1 class="app-title">星火聊天室</h1>

        <div class="header-actions">
            <div class="theme-menu">
                <button class="header-button theme-button" id="theme-button" title="切换主题">
                    <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"
                              stroke="currentColor" stroke-width="2"/>
                        <path d="M12 2V4M12 20V22M4 12H2M22 12H20M19.0711 19.0711L17.6569 17.6569M6.34315 6.34315L4.92893 4.92893M19.0711 4.92893L17.6569 6.34315M6.34315 17.6569L4.92893 19.0711"
                              stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                    </svg>
                </button>
                <div class="theme-options">
                    <div class="theme-option theme-default" data-theme="default">
                        <span class="theme-color"></span>
                        <span>默认主题</span>
                    </div>
                    <div class="theme-option theme-blue" data-theme="blue">
                        <span class="theme-color"></span>
                        <span>蓝色主题</span>
                    </div>
                    <div class="theme-option theme-purple" data-theme="purple">
                        <span class="theme-color"></span>
                        <span>紫色主题</span>
                    </div>
                    <div class="theme-option theme-dark" data-theme="dark">
                        <span class="theme-color"></span>
                        <span>深色主题</span>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="chat-container">
        <div class="model-selector">
            <label for="model-select">模型选择</label>
            <select id="model-select">
                <!-- 模型选项将通过JavaScript动态加载 -->
            </select>
        </div>

        <div class="chat-history" id="chat-history">
            <!-- 空状态提示 -->
            <div class="empty-state" id="empty-state">
                <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M8 12H8.01M12 12H12.01M16 12H16.01M21 12C21 16.4183 16.9706 20 12 20C10.4609 20 9.01172 19.6565 7.74457 19.0511L3 20L4.39499 16.28C3.51156 15.0423 3 13.5743 3 12C3 7.58172 7.02944 4 12 4C16.9706 4 21 7.58172 21 12Z"
                          stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
                <h3>开始新的对话</h3>
                <p>输入消息开始与星火大模型交流</p>
            </div>
        </div>

        <div class="input-area">
                <textarea
                        id="message-input"
                        placeholder="输入消息..."
                        autocomplete="off"
                        rows="1"
                ></textarea>
            <button id="send-button" title="发送">
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M22 2L11 13" stroke="white" stroke-width="2" stroke-linecap="round"
                          stroke-linejoin="round"/>
                    <path d="M22 2L15 22L11 13L2 9L22 2Z" stroke="white" stroke-width="2" stroke-linecap="round"
                          stroke-linejoin="round"/>
                </svg>
            </button>
        </div>

        <div class="status" id="status"></div>
    </div>
</div>

<script>
    // ==================== 粒子系统 ====================
    const particleOpts = {
        particleColor: "hsl(180, 80%, 60%)",
        lineColor: "hsl(180, 80%, 60%)",
        particleAmount: 120, // 增加粒子数量
        defaultSpeed: 0.5,
        variantSpeed: 0.1,
        defaultRadius: 2,
        variantRadius: 2,
        linkRadius: 200,
        colorChangeSpeed: 0.5,
        hueRange: 60
    };

    let particleCanvas = document.getElementById("particle-canvas");
    let particleCtx = particleCanvas.getContext("2d");
    let pW, pH;
    let particles = [];
    let hueOffset = 0;
    let mouseX = -1000;
    let mouseY = -1000;
    let mouseRadius = 150;
    let delay = 200;
    let tid;
    let rgb = particleOpts.lineColor.match(/\d+/g);

    // 窗口大小调整
    function resizeParticleCanvas() {
        pW = particleCanvas.width = window.innerWidth;
        pH = particleCanvas.height = window.innerHeight;

        // 根据窗口大小调整粒子数量
        const area = pW * pH;
        particleOpts.particleAmount = Math.floor(area / 3000); // 更密集的粒子
        if (particleOpts.particleAmount < 50) particleOpts.particleAmount = 50; // 最小数量
        if (particleOpts.particleAmount > 200) particleOpts.particleAmount = 200; // 最大数量

        // 重新初始化粒子
        particles = [];
        for (let i = 0; i < particleOpts.particleAmount; i++) {
            particles.push(new Particle());
        }
    }

    // 防抖函数
    function debounceResize() {
        clearTimeout(tid);
        tid = setTimeout(function () {
            resizeParticleCanvas();
        }, delay);
    };

    // 计算两点距离
    function checkDistance(x1, y1, x2, y2) {
        return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
    }

    // 连接点
    function linkParticles(point1, hubs) {
        for (let i = 0; i < hubs.length; i++) {
            let distance = checkDistance(point1.x, point1.y, hubs[i].x, hubs[i].y);
            let opacity = 1 - distance / particleOpts.linkRadius;

            if (opacity > 0) {
                particleCtx.lineWidth = 0.5;
                particleCtx.strokeStyle = `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${opacity * 0.3})`;
                particleCtx.beginPath();
                particleCtx.moveTo(point1.x, point1.y);
                particleCtx.lineTo(hubs[i].x, hubs[i].y);
                particleCtx.closePath();
                particleCtx.stroke();
            }
        }
    }

    // 粒子构造函数
    function Particle(xPos, yPos) {
        this.x = Math.random() * pW;
        this.y = Math.random() * pH;
        this.speed = particleOpts.defaultSpeed + Math.random() * particleOpts.variantSpeed;
        this.directionAngle = Math.floor(Math.random() * 360);
        this.color = particleOpts.particleColor;
        this.radius = particleOpts.defaultRadius + Math.random() * particleOpts.variantRadius;
        this.vector = {
            x: Math.cos(this.directionAngle) * this.speed,
            y: Math.sin(this.directionAngle) * this.speed
        };

        this.update = function () {
            this.border();

            // 鼠标交互效果
            const distanceToMouse = checkDistance(this.x, this.y, mouseX, mouseY);
            if (distanceToMouse < mouseRadius) {
                const angle = Math.atan2(this.y - mouseY, this.x - mouseX);
                const force = (mouseRadius - distanceToMouse) / mouseRadius * 2;
                this.vector.x += Math.cos(angle) * force;
                this.vector.y += Math.sin(angle) * force;
            }

            this.x += this.vector.x;
            this.y += this.vector.y;
        };

        this.border = function () {
            if (this.x >= pW || this.x <= 0) {
                this.vector.x *= -1;
            }
            if (this.y >= pH || this.y <= 0) {
                this.vector.y *= -1;
            }
            if (this.x > pW) this.x = pW;
            if (this.y > pH) this.y = pH;
            if (this.x < 0) this.x = 0;
            if (this.y < 0) this.y = 0;
        };

        this.draw = function () {
            particleCtx.beginPath();
            particleCtx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
            particleCtx.closePath();
            particleCtx.fillStyle = this.color;
            particleCtx.fill();
        };
    }

    // 颜色更新函数
    function updateParticleColors() {
        hueOffset += particleOpts.colorChangeSpeed;
        if (hueOffset >= 360) hueOffset = 0;

        const hue = (180 + hueOffset) % 360;
        const particleHue = (hue + Math.random() * particleOpts.hueRange - particleOpts.hueRange / 2) % 360;
        const lineHue = (hue + Math.random() * particleOpts.hueRange - particleOpts.hueRange / 2) % 360;

        particleOpts.particleColor = `hsl(${particleHue}, 80%, 60%)`;
        particleOpts.lineColor = `hsl(${lineHue}, 80%, 60%)`;
        rgb = particleOpts.lineColor.match(/\d+/g);
    }

    // 根据主题更新粒子颜色
    function updateParticleColorForTheme(theme) {
        let hue;
        switch (theme) {
            case 'blue':
                hue = 210;
                break;
            case 'purple':
                hue = 280;
                break;
            case 'dark':
                hue = 120;
                break;
            default:
                hue = 180;
        }
        particleOpts.particleColor = `hsl(${hue}, 80%, 60%)`;
        particleOpts.lineColor = `hsl(${hue}, 80%, 60%)`;
        rgb = particleOpts.lineColor.match(/\d+/g);
    }

    // 初始化粒子系统
    function setupParticles() {
        particles = [];
        resizeParticleCanvas();
        for (let i = 0; i < particleOpts.particleAmount; i++) {
            particles.push(new Particle());
        }
        particleLoop();
    }

    // 粒子主循环
    function particleLoop() {
        requestAnimationFrame(particleLoop);
        particleCtx.clearRect(0, 0, pW, pH);

        updateParticleColors();

        for (let i = 0; i < particles.length; i++) {
            particles[i].update();
            particles[i].draw();
        }

        for (let i = 0; i < particles.length; i++) {
            linkParticles(particles[i], particles);
        }
    }

    // 事件监听
    window.addEventListener('resize', debounceResize);

    window.addEventListener('mousemove', function (e) {
        mouseX = e.clientX;
        mouseY = e.clientY;
    });

    window.addEventListener('touchmove', function (e) {
        e.preventDefault();
        mouseX = e.touches[0].clientX;
        mouseY = e.touches[0].clientY;
    }, {passive: false});

    window.addEventListener('touchend', function () {
        mouseX = -1000;
        mouseY = -1000;
    });

    // 启动粒子系统
    setupParticles();

    // ==================== 聊天系统 ====================
    document.addEventListener('DOMContentLoaded', function () {
        const chatHistory = document.getElementById('chat-history');
        const messageInput = document.getElementById('message-input');
        const sendButton = document.getElementById('send-button');
        const modelSelect = document.getElementById('model-select');
        const statusDisplay = document.getElementById('status');
        const newChatButton = document.getElementById('new-chat-button');
        const emptyState = document.getElementById('empty-state');
        const themeOptions = document.querySelectorAll('.theme-option');
        const appContainer = document.querySelector('.app-container');
        const sidebar = document.getElementById('sidebar');
        const sidebarToggle = document.getElementById('sidebar-toggle');
        const sidebarClose = document.getElementById('sidebar-close');
        const sidebarOverlay = document.getElementById('sidebar-overlay');
        const historyList = document.getElementById('history-list');
        const historySearch = document.getElementById('history-search');
        const clearHistoryButton = document.getElementById('clear-history');

        let conversationId = 'conv_' + Date.now();
        let currentModel = 'lite';
        let isProcessing = false;
        let messages = [];
        let conversations = [];
        let activeConversationIndex = -1;

        // 加载对话历史
        function loadConversations() {
            const savedConversations = localStorage.getItem('chat-conversations');
            if (savedConversations) {
                conversations = JSON.parse(savedConversations);
                renderConversationList();
                if (conversations.length > 0) {
                    loadConversation(conversations[0].id);
                }
            }
        }

        // 保存对话历史
        function saveConversations() {
            localStorage.setItem('chat-conversations', JSON.stringify(conversations));
        }

        // 渲染对话列表
        function renderConversationList(filter = '') {
            historyList.innerHTML = '';

            // 过滤对话
            const filteredConversations = conversations.filter(conv =>
                conv.title.toLowerCase().includes(filter.toLowerCase()) ||
                conv.messages.some(msg => msg.content.toLowerCase().includes(filter.toLowerCase()))
            );

            // 按时间排序
            filteredConversations.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt));

            filteredConversations.forEach((conversation, index) => {
                const li = document.createElement('li');
                li.className = `history-item ${conversation.id === conversationId ? 'active' : ''}`;
                li.dataset.id = conversation.id;

                // 获取最后一条用户消息作为预览
                const lastUserMessage = conversation.messages.findLast(msg => msg.role === 'user');
                const preview = lastUserMessage ? lastUserMessage.content.substring(0, 30) : '新对话';

                li.innerHTML = `
                    <div class="history-item-title">${conversation.title}</div>
                    <div class="history-item-preview">${preview}${preview.length === 30 ? '...' : ''}</div>
                    <div class="history-item-time">${formatConversationTime(conversation.updatedAt)}</div>
                `;

                li.addEventListener('click', () => {
                    loadConversation(conversation.id);
                    if (window.innerWidth <= 900) {
                        toggleSidebar();
                    }
                });

                historyList.appendChild(li);
            });
        }

        // 格式化对话时间
        function formatConversationTime(timestamp) {
            const now = new Date();
            const date = new Date(timestamp);
            const diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));

            if (diffDays === 0) {
                return date.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'});
            } else if (diffDays === 1) {
                return '昨天';
            } else if (diffDays < 7) {
                return `${diffDays}天前`;
            } else {
                return date.toLocaleDateString([], {month: 'numeric', day: 'numeric'});
            }
        }

        // 加载对话
        function loadConversation(id) {
            const conversation = conversations.find(conv => conv.id === id);
            if (!conversation) return;

            conversationId = id;
            messages = [...conversation.messages];
            activeConversationIndex = conversations.findIndex(conv => conv.id === id);

            renderMessages(messages);
            renderConversationList(historySearch.value);

            // 更新标题
            document.title = `${conversation.title} - 星火聊天室`;
            messageInput.focus();
        }

        // 保存当前对话
        function saveCurrentConversation() {
            const index = conversations.findIndex(conv => conv.id === conversationId);
            const title = generateConversationTitle(messages);

            if (index !== -1) {
                // 更新现有对话
                conversations[index] = {
                    ...conversations[index],
                    title,
                    messages,
                    updatedAt: new Date().toISOString()
                };
            } else if (messages.length > 0) {
                // 添加新对话
                conversations.unshift({
                    id: conversationId,
                    title,
                    messages,
                    createdAt: new Date().toISOString(),
                    updatedAt: new Date().toISOString()
                });
            }

            saveConversations();
            renderConversationList(historySearch.value);
        }

        // 生成对话标题
        function generateConversationTitle(messages) {
            if (messages.length === 0) return '新对话';

            // 获取第一条用户消息
            const firstUserMessage = messages.find(msg => msg.role === 'user');
            if (!firstUserMessage) return '新对话';

            const content = firstUserMessage.content;

            // 提取前几个词作为标题
            const words = content.trim().split(/\s+/);
            if (words.length <= 5) {
                return content.substring(0, 30);
            } else {
                return words.slice(0, 3).join(' ') + '...';
            }
        }

        // 切换侧边栏
        function toggleSidebar() {
            sidebar.classList.toggle('active');
            sidebarOverlay.classList.toggle('active');
        }

        // 清空历史记录
        function clearAllHistory() {
            if (confirm('确定要清空所有历史记录吗？此操作不可撤销。')) {
                conversations = [];
                saveConversations();
                renderConversationList();

                // 如果当前对话是历史记录中的，保留为新对话
                if (activeConversationIndex === -1) {
                    conversationId = 'conv_' + Date.now();
                    messages = [];
                    renderMessages([]);
                }
            }
        }

        // 加载可用模型
        function loadModels() {
            fetch('/api/models')
                    .then(response => {
                        if (!response.ok) throw new Error('网络响应异常');
                        return response.json();
                    })
                    .then(data => {
                        modelSelect.innerHTML = '';
                        data.models.forEach(model => {
                            const option = document.createElement('option');
                            option.value = model.id;
                            option.textContent = model.name;
                            modelSelect.appendChild(option);
                        });
                        currentModel = modelSelect.value;
                    })
                    .catch(error => {
                        console.error('加载模型列表失败:', error);
                        showStatusMessage('加载模型列表失败，使用默认模型');

                        // 添加默认选项
                        const defaultModels = [
                            {id: 'lite', name: '星火Lite'},
                            {id: 'pro', name: '星火Pro'},
                            {id: 'max', name: '星火Max'}
                        ];

                        defaultModels.forEach(model => {
                            const option = document.createElement('option');
                            option.value = model.id;
                            option.textContent = model.name;
                            modelSelect.appendChild(option);
                        });
                    });
        }

        // 初始化聊天
        function initChat() {
            loadModels();
            loadConversations();
            checkEmptyState();
        }

        // 检查空状态
        function checkEmptyState() {
            if (messages.length === 0) {
                emptyState.style.display = 'flex';
            } else {
                emptyState.style.display = 'none';
            }
        }

        // 模型选择变化事件
        modelSelect.addEventListener('change', function () {
            currentModel = this.value;
            showStatusMessage(`已切换到: ${this.options[this.selectedIndex].text}`);
        });

        // 发送消息
        function sendMessage() {
            const message = messageInput.value.trim();
            if (!message || isProcessing) return;

            // 清空输入框并重置高度
            messageInput.value = '';
            adjustInputHeight();

            isProcessing = true;
            sendButton.disabled = true;
            showTypingIndicator();

            // 如果是新对话，保存当前对话状态
            if (activeConversationIndex === -1) {
                saveCurrentConversation();
            }

            // 添加用户消息到聊天历史
            addMessage('user', message);
            messages.push({role: 'user', content: message});

            // 发送请求到后端
            fetch('/api/chat', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    message: message,
                    conversation_id: conversationId,
                    model_type: currentModel
                })
            })
                    .then(response => {
                        if (!response.ok) throw new Error(`HTTP错误! 状态: ${response.status}`);
                        return response.json();
                    })
                    .then(data => {
                        if (data.error) throw new Error(data.error);
                        pollResponse();
                    })
                    .catch(error => {
                        console.error('发送消息失败:', error);
                        showStatusMessage('发送失败: ' + error.message);
                        isProcessing = false;
                        sendButton.disabled = false;
                    });
        }

        // 轮询获取响应
        function pollResponse() {
            fetch(`/api/history/${conversationId}`)
                    .then(response => {
                        if (!response.ok) throw new Error('获取历史记录失败');
                        return response.json();
                    })
                    .then(data => {
                        messages = data.history || [];
                        renderMessages(messages);

                        // 检查是否完成
                        const lastMessage = messages[messages.length - 1];
                        if (lastMessage && lastMessage.role === 'assistant') {
                            completeResponse();
                        } else {
                            setTimeout(pollResponse, 500);
                        }
                    })
                    .catch(error => {
                        console.error('获取响应失败:', error);
                        showStatusMessage('获取响应时出错');
                        completeResponse();
                    });
        }

        // 渲染所有消息
        function renderMessages(messages) {
            chatHistory.innerHTML = '';
            messages.forEach(msg => {
                if (msg.role === 'assistant') {
                    try {
                        // 尝试解析可能包含思维链的JSON内容
                        const contentObj = JSON.parse(msg.content);
                        if (contentObj.reasoning_content) {
                            addMessage('reasoning', contentObj.reasoning_content, false);
                        }
                        addMessage('assistant', contentObj.content || msg.content, false);
                    } catch (e) {
                        addMessage('assistant', msg.content, false);
                    }
                } else if (msg.role === 'user') {
                    addMessage('user', msg.content, false);
                }
            });
            scrollToBottom();
            checkEmptyState();
        }

        // 完成响应处理
        function completeResponse() {
            isProcessing = false;
            sendButton.disabled = false;
            clearStatus();
            scrollToBottom();

            // 保存对话
            saveCurrentConversation();
        }

        // 添加消息到聊天历史
        function addMessage(role, content, shouldScroll = true) {
            if (!content) return;

            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${role}-message`;

            if (role === 'reasoning') {
                messageDiv.innerHTML = `
                        <div class="reasoning-message">${formatContent(content)}</div>
                    `;
            } else {
                const sender = role === 'user' ? '你' : getModelName();
                messageDiv.innerHTML = `
                        <div class="message-bubble">${formatContent(content)}</div>
                        <div class="message-meta">
                            <span>${sender}</span>
                            <span>${formatTime()}</span>
                        </div>
                    `;
            }

            chatHistory.appendChild(messageDiv);
            if (shouldScroll) scrollToBottom();
            checkEmptyState();
        }

        // 格式化内容
        function formatContent(content) {
            return content
                    .replace(/&/g, "&amp;")
                    .replace(/</g, "&lt;")
                    .replace(/>/g, "&gt;")
                    .replace(/\n/g, '<br>')
                    .replace(/  /g, ' &nbsp;');
        }

        // 获取当前模型名称
        function getModelName() {
            return modelSelect.options[modelSelect.selectedIndex]?.text || 'AI助手';
        }

        // 格式化时间
        function formatTime() {
            const now = new Date();
            return now.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'});
        }

        // 滚动到底部
        function scrollToBottom() {
            chatHistory.scrollTop = chatHistory.scrollHeight;
        }

        // 调整输入框高度
        function adjustInputHeight() {
            messageInput.style.height = 'auto';
            messageInput.style.height = `${Math.min(messageInput.scrollHeight, 120)}px`;
        }

        // 显示输入指示器
        function showTypingIndicator() {
            statusDisplay.innerHTML = `
                    <div class="typing-indicator">
                        <span>${getModelName()}正在输入</span>
                        <div class="typing-dot"></div>
                        <div class="typing-dot"></div>
                        <div class="typing-dot"></div>
                    </div>
                `;
        }

        // 显示状态消息
        function showStatusMessage(message) {
            statusDisplay.textContent = message;
            setTimeout(clearStatus, 5000);
        }

        // 清除状态
        function clearStatus() {
            statusDisplay.textContent = '';
        }

        // 开始新对话
        function startNewChat() {
            if (isProcessing) {
                return;
            }

            // 保存当前对话
            if (messages.length > 0) {
                saveCurrentConversation();
            }

            // 创建新对话
            conversationId = 'conv_' + Date.now();
            messages = [];
            activeConversationIndex = -1;
            chatHistory.innerHTML = '';
            checkEmptyState();
            showStatusMessage('已开始新对话');
            messageInput.focus();

            // 更新标题
            document.title = '星火聊天室';
        }

        // 切换主题
        function changeTheme(theme) {
            // 移除所有主题类
            appContainer.classList.remove('theme-blue', 'theme-purple', 'theme-dark');

            // 添加选定的主题类
            if (theme !== 'default') {
                appContainer.classList.add(`theme-${theme}`);
            }

            // 更新粒子颜色
            updateParticleColorForTheme(theme);

            // 保存主题偏好
            localStorage.setItem('chat-theme', theme);
        }

        // 输入框事件监听
        messageInput.addEventListener('input', adjustInputHeight);
        messageInput.addEventListener('keydown', function (e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendMessage();
            }
        });

        // 发送按钮点击事件
        sendButton.addEventListener('click', sendMessage);

        // 新对话按钮点击事件
        newChatButton.addEventListener('click', startNewChat);

        // 侧边栏切换事件
        sidebarToggle.addEventListener('click', toggleSidebar);
        sidebarClose.addEventListener('click', toggleSidebar);
        sidebarOverlay.addEventListener('click', toggleSidebar);

        // 历史记录搜索事件
        historySearch.addEventListener('input', function() {
            renderConversationList(this.value);
        });

        // 清空历史记录事件
        clearHistoryButton.addEventListener('click', clearAllHistory);

        // 主题切换事件
        themeOptions.forEach(option => {
            option.addEventListener('click', function () {
                const theme = this.dataset.theme;
                changeTheme(theme);
                showStatusMessage(`已切换到${this.querySelector('span:last-child').textContent}`);
            });
        });

        // 页面加载时初始化
        function init() {
            // 加载保存的主题
            const savedTheme = localStorage.getItem('chat-theme') || 'default';
            changeTheme(savedTheme);

            // 初始化聊天
            initChat();

            // 自动聚焦输入框
            messageInput.focus();
        }

        // 启动应用
        init();
    });
</script>
</body>
</html>